/*
 * Copyright (c) 2003-2005
 * XDoclet Team
 * All rights reserved.
 */
package org.xdoclet.plugin.hibernate;

import java.io.FileInputStream;
import java.io.IOException;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.collections.CollectionUtils;

import org.generama.JellyTemplateEngine;
import org.generama.QDoxCapableMetadataProvider;
import org.generama.WriterMapper;

import org.generama.defaults.XMLOutputValidator;

import org.xdoclet.plugin.hibernate.qtags.TagLibrary;

import org.xdoclet.predicate.HasTag;

import com.thoughtworks.qdox.model.JavaClass;

/**
 * plugin producing hibernate config file
 * 
 * @author Inger
 * @author Konstantin Pribluda
 */
public class HibernateConfigPlugin extends AbstractHibernatePlugin {
	private Collection allClasses;

	private String c3p0acquireincrement;

	private String c3p0idletestperiod;

	private String c3p0maxsize;

	private String c3p0maxstatements;

	private String c3p0minsize;

	private String c3p0timeout;

	private String cacheprovider;

	private String cachequerycachefactory;

	private String cacheregionprefix;

	private String cacheuseminimalputs;

	private String cacheusequerycache;

	private String connectionprovider;

	private String currentsessioncontextclass;

	private String defaultentitymode;

	private String defaultschema;

	private String dialect;

	private boolean dontaddmappings;

	private String hbm2ddlauto;

	private String jdbcautocommit;

	private String jdbcautoreconnect;

	private String jdbcautoreconnectforpools;

	private String jdbcbatchsize;

	private String jdbcbatchversioneddata;

	private String jdbcdriver;

	private String jdbcfetchsize;

	private String jdbcisconnectionvalidationrequired;

	private String jdbcisolation;

	private String jdbcpassword;

	private String jdbcpoolsize;

	private String jdbcurl;

	private String jdbcusegetgeneratedkeys;

	private String jdbcusername;

	private String jdbcusescrollableresultset;

	private String jdbcusestreamsforbinary;

	private String jndiclass;

	private String jndidatasource;

	private String jndisessionfactoryname;

	private String jndiurl;

	private String jtausertransaction;

	private String mappingExtension;

	private String maxfetchdepth;

	private Properties props;

	private String querysubstitutions;

	private String showsql;

	private String transactionfactory;

	private String transactionmanagerlookup;

	private String useouterjoin;

	private String usereflectionoptimizer;

	private String usesecondlevelcache;

	public HibernateConfigPlugin(JellyTemplateEngine jellyTemplateEngine,
			QDoxCapableMetadataProvider metadataProvider,
			WriterMapper writerMapper) {
		super(jellyTemplateEngine, metadataProvider, writerMapper);
		setFilereplace("hibernate.cfg.xml");
		setMultioutput(false);
		setMappingextension(".hbm.xml");
		Map dtds = new HashMap();
		dtds
				.put(
						"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd",
						getClass().getResource(
								"dtd/hibernate-configuration-2.0.dtd"));
		dtds
				.put(
						"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd",
						getClass().getResource(
								"dtd/hibernate-configuration-3.0.dtd"));
		setOutputValidator(new XMLOutputValidator(dtds));
		new TagLibrary(metadataProvider);
		this.props = new Properties();
	}

	public String getC3p0acquireincrement() {
		return c3p0acquireincrement;
	}

	public String getC3p0idletestperiod() {
		return c3p0idletestperiod;
	}

	public String getC3p0maxsize() {
		return c3p0maxsize;
	}

	public String getC3p0maxstatements() {
		return c3p0maxstatements;
	}

	public String getC3p0minsize() {
		return c3p0minsize;
	}

	public String getC3p0timeout() {
		return c3p0timeout;
	}

	public String getCacheprovider() {
		return cacheprovider;
	}

	public String getCachequerycachefactory() {
		return cachequerycachefactory;
	}

	public String getCacheregionprefix() {
		return cacheregionprefix;
	}

	public String getCacheuseminimalputs() {
		return cacheuseminimalputs;
	}

	public String getCacheusequerycache() {
		return cacheusequerycache;
	}

	public String getConnectionprovider() {
		return connectionprovider;
	}

	/**
	 * defines property hibernate.current_session_context_class
	 * 
	 * @return
	 */
	public String getCurrentsessioncontextclass() {
		return currentsessioncontextclass;
	}

	/**
	 * defined
	 * 
	 * @return
	 */
	public String getDefaultentitymode() {
		return defaultentitymode;
	}

	public String getDefaultschema() {
		return defaultschema;
	}

	public String getDialect() {
		return dialect;
	}

	public String getHbm2ddlauto() {
		return hbm2ddlauto;
	}

	public String getJdbcautocommit() {
		return jdbcautocommit;
	}

	public String getJdbcautoreconnect() {
		return jdbcautoreconnect;
	}

	public String getJdbcautoreconnectforpools() {
		return jdbcautoreconnectforpools;
	}

	public String getJdbcbatchsize() {
		return jdbcbatchsize;
	}

	public String getJdbcbatchversioneddata() {
		return jdbcbatchversioneddata;
	}

	public String getJdbcdriver() {
		return jdbcdriver;
	}

	public String getJdbcfetchsize() {
		return jdbcfetchsize;
	}

	public String getJdbcisconnectionvalidationrequired() {
		return jdbcisconnectionvalidationrequired;
	}

	public String getJdbcisolation() {
		return jdbcisolation;
	}

	public String getJdbcpassword() {
		return jdbcpassword;
	}

	public String getJdbcpoolsize() {
		return jdbcpoolsize;
	}

	public String getJdbcurl() {
		return jdbcurl;
	}

	public String getJdbcusegetgeneratedkeys() {
		return jdbcusegetgeneratedkeys;
	}

	public String getJdbcusername() {
		return jdbcusername;
	}

	/**
	 * configure usage of scrolable result set
	 * 
	 * @return
	 */
	public String getJdbcusescrollableresultset() {
		return jdbcusescrollableresultset;
	}

	public String getJdbcusestreamsforbinary() {
		return jdbcusestreamsforbinary;
	}

	public String getJndiclass() {
		return jndiclass;
	}

	public String getJndidatasource() {
		return jndidatasource;
	}

	public String getJndisessionfactoryname() {
		return jndisessionfactoryname;
	}

	public String getJndiurl() {
		return jndiurl;
	}

	public String getJtausertransaction() {
		return jtausertransaction;
	}

	public Collection getMappedClasses() {
		if (allClasses == null) {
			allClasses = metadataProvider.getMetadata();
		}

		return CollectionUtils.select(allClasses, new HasTag("hibernate.class",
				null, null, false));
	}

	public String getMappingPath(JavaClass clazz) {
		return clazz.getFullyQualifiedName().replace('.', '/')
				+ mappingExtension;
	}

	public String getMaxfetchdepth() {
		return maxfetchdepth;
	}

	public Map getPropertyMap() {
		return props;
	}

	public String getQuerysubstitutions() {
		return querysubstitutions;
	}

	public String getShowsql() {
		return showsql;
	}

	public String getTransactionfactory() {
		return transactionfactory;
	}

	public String getTransactionmanagerlookup() {
		return transactionmanagerlookup;
	}

	public String getUseouterjoin() {
		return useouterjoin;
	}

	public String getUsereflectionoptimizer() {
		return usereflectionoptimizer;
	}

	public String getUsesecondlevelcache() {
		return usesecondlevelcache;
	}

	/**
	 * whether to supress inclusion of mappings in configuration. no effect  
     * if hibernate 2.0 is used ( always false ) 
	 * @return
	 */
	public boolean isDontaddmappings() {
		return dontaddmappings && !getDTDVersion().equals(HibernateVersion.getValues()[0]);
	}

	/**
	 * hibernate.c3p0.acquire_increment
	 */
	public void setC3p0acquireincrement(String c3p0acquireincrement) {
		this.c3p0acquireincrement = c3p0acquireincrement;
	}

	/**
	 * hibernate.c3p0.idle_test_period
	 */
	public void setC3p0idletestperiod(String c3p0idletestperiod) {
		this.c3p0idletestperiod = c3p0idletestperiod;
	}

	/**
	 * hibernate.c3p0.max_size
	 */
	public void setC3p0maxsize(String c3p0maxsize) {
		this.c3p0maxsize = c3p0maxsize;
	}

	/**
	 * hibernate.c3p0.max_statements
	 */
	public void setC3p0maxstatements(String c3p0maxstatements) {
		this.c3p0maxstatements = c3p0maxstatements;
	}

	/**
	 * hibernate.c3p0.min_size
	 */
	public void setC3p0minsize(String c3p0minsize) {
		this.c3p0minsize = c3p0minsize;
	}

	/**
	 * hibernate.c3p0.timeout
	 */
	public void setC3p0timeout(String c3p0timeout) {
		this.c3p0timeout = c3p0timeout;
	}

	/**
	 * hibernate.cache.provider_class
	 */
	public void setCacheprovider(String cacheprovider) {
		this.cacheprovider = cacheprovider;
	}

	/**
	 * hibernate.cache.query_cache_factory
	 */
	public void setCachequerycachefactory(String cachequerycachefactory) {
		this.cachequerycachefactory = cachequerycachefactory;
	}

	/**
	 * hibernate.cache.region_prefix
	 */
	public void setCacheregionprefix(String cacheregionprefix) {
		this.cacheregionprefix = cacheregionprefix;
	}

	/**
	 * hibernate.cache.use_minimal_puts
	 */
	public void setCacheuseminimalputs(String cacheuseminimalputs) {
		this.cacheuseminimalputs = cacheuseminimalputs;
	}

	/**
	 * hibernate.cache.use_query_cache
	 */
	public void setCacheusequerycache(String cacheusequerycache) {
		this.cacheusequerycache = cacheusequerycache;
	}

	/**
	 * hibernate.connection.provider_class
	 */
	public void setConnectionprovider(String connectionprovider) {
		this.connectionprovider = connectionprovider;
	}

	public void setCurrentsessioncontextclass(String currentSessionContextClass) {
		this.currentsessioncontextclass = currentSessionContextClass;
	}

	/**
	 * hibernate.default_entity_mode
	 */
	public void setDefaultentitymode(String defaultentitymode) {
		this.defaultentitymode = defaultentitymode;
	}

	/**
	 * hibernate.default_schema
	 */
	public void setDefaultschema(String defaultschema) {
		this.defaultschema = defaultschema;
	}

	/**
	 * hibernate.dialect
	 */
	public void setDialect(String dialect) {
		this.dialect = dialect;
	}

	public void setDontaddmappings(boolean dontaddmappings) {
		this.dontaddmappings = dontaddmappings;
	}

	/**
	 * hibernate.hbm2ddl.auto
	 */
	public void setHbm2ddlauto(String hbm2ddlauto) {
		this.hbm2ddlauto = hbm2ddlauto;
	}

	/**
	 * hibernate.connection.autocommit
	 */
	public void setJdbcautocommit(String jdbcautocommit) {
		this.jdbcautocommit = jdbcautocommit;
	}

	/**
	 * hibernate.connection.autoReconnect
	 */
	public void setJdbcautoreconnect(String jdbcautoreconnect) {
		this.jdbcautoreconnect = jdbcautoreconnect;
	}

	/**
	 * hibernate.connection.autoReconnectForPools
	 */
	public void setJdbcautoreconnectforpools(String jdbcautoreconnectforpools) {
		this.jdbcautoreconnectforpools = jdbcautoreconnectforpools;
	}

	/**
	 * hibernate.jdbc.batch_size
	 */
	public void setJdbcbatchsize(String jdbcbatchsize) {
		this.jdbcbatchsize = jdbcbatchsize;
	}

	/**
	 * hibernate.jdbc.batch_versioned_data
	 */
	public void setJdbcbatchversioneddata(String jdbcbatchversioneddata) {
		this.jdbcbatchversioneddata = jdbcbatchversioneddata;
	}

	/**
	 * hibernate.connection.driver_class
	 */
	public void setJdbcdriver(String jdbcdriver) {
		this.jdbcdriver = jdbcdriver;
	}

	/**
	 * hibernate.jdbc.fetch_size
	 */
	public void setJdbcfetchsize(String jdbcfetchsize) {
		this.jdbcfetchsize = jdbcfetchsize;
	}

	/**
	 * hibernate.connection.is-connection-validation-required
	 */
	public void setJdbcisconnectionvalidationrequired(
			String jdbcisconnectionvalidationrequired) {
		this.jdbcisconnectionvalidationrequired = jdbcisconnectionvalidationrequired;
	}

	/**
	 * hibernate.connection.isolation
	 */
	public void setJdbcisolation(String jdbcisolation) {
		this.jdbcisolation = jdbcisolation;
	}

	/**
	 * hibernate.connection.password
	 */
	public void setJdbcpassword(String jdbcpassword) {
		this.jdbcpassword = jdbcpassword;
	}

	/**
	 * hibernate.connection.pool_size
	 */
	public void setJdbcpoolsize(String jdbcpoolsize) {
		this.jdbcpoolsize = jdbcpoolsize;
	}

	/**
	 * hibernate.connection.url
	 */
	public void setJdbcurl(String jdbcurl) {
		this.jdbcurl = jdbcurl;
	}

	/**
	 * hibernate.jdbc.use_get_generated_keys
	 */
	public void setJdbcusegetgeneratedkeys(String jdbcusegetgeneratedkeys) {
		this.jdbcusegetgeneratedkeys = jdbcusegetgeneratedkeys;
	}

	/**
	 * hibernate.connection.username
	 */
	public void setJdbcusername(String jdbcusername) {
		this.jdbcusername = jdbcusername;
	}

	/**
	 * hibernate.jdbc.use_scrollable_resultset
	 */
	public void setJdbcusescrollableresultset(String jdbcusescrollableresultset) {
		this.jdbcusescrollableresultset = jdbcusescrollableresultset;
	}

	/**
	 * hibernate.jdbc.use_streams_for_binary
	 */
	public void setJdbcusestreamsforbinary(String jdbcusestreamsforbinary) {
		this.jdbcusestreamsforbinary = jdbcusestreamsforbinary;
	}

	/**
	 * hibernate.jndi.class
	 */
	public void setJndiclass(String jndiclass) {
		this.jndiclass = jndiclass;
	}

	/**
	 * hibernate.connection.datasource
	 */
	public void setJndidatasource(String jndidatasource) {
		this.jndidatasource = jndidatasource;
	}

	/**
	 * hibernate.session_factory_name
	 */
	public void setJndisessionfactoryname(String jndisessionfactoryname) {
		this.jndisessionfactoryname = jndisessionfactoryname;
	}

	/**
	 * hibernate.jndi.url
	 */
	public void setJndiurl(String jndiurl) {
		this.jndiurl = jndiurl;
	}

	/**
	 * jta.UserTransaction
	 */
	public void setJtausertransaction(String jtausertransaction) {
		this.jtausertransaction = jtausertransaction;
	}

	public void setMappingextension(String mappingExtension) {
		this.mappingExtension = mappingExtension;
	}

	/**
	 * hibernate.max_fetch_depth
	 */
	public void setMaxfetchdepth(String maxfetchdepth) {
		this.maxfetchdepth = maxfetchdepth;
	}

	/**
	 * file name of properties file containing hibernate properties
	 */
	public void setProperties(String properties) {
		FileInputStream fis = null;

		try {
			fis = new FileInputStream(properties);
			props.load(fis);
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
			} catch (IOException e) {
			}
		}
	}

	/**
	 * hibernate.query.substitutions
	 */
	public void setQuerysubstitutions(String querysubstitutions) {
		this.querysubstitutions = querysubstitutions;
	}

	/**
	 * hibernate.show_sql
	 */
	public void setShowsql(String showsql) {
		this.showsql = showsql;
	}

	/**
	 * hibernate.transaction.factory_class
	 */
	public void setTransactionfactory(String transactionfactory) {
		this.transactionfactory = transactionfactory;
	}

	/**
	 * hibernate.transaction.manager_lookup_class
	 */
	public void setTransactionmanagerlookup(String transactionmanagerlookup) {
		this.transactionmanagerlookup = transactionmanagerlookup;
	}

	/**
	 * hibernate.use_outer_join
	 */
	public void setUseouterjoin(String useouterjoin) {
		this.useouterjoin = useouterjoin;
	}

	/**
	 * hibernate.cglib.use_reflection_optimizer
	 */
	public void setUsereflectionoptimizer(String usereflectionoptimizer) {
		this.usereflectionoptimizer = usereflectionoptimizer;
	}

	public void setUsesecondlevelcache(String usesecondlevelcache) {
		this.usesecondlevelcache = usesecondlevelcache;
	}
}